<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of soaUsers
 *
 * @author dxx
 */

namespace app\common\model\activity;
use think\Model;

class Coupons extends Model {

    protected $table = 'coupons';
    protected $connection = ['database' => 'activity'];
    private $expire = 86400 * 95;
    private $couponsExistsCodeKey = 'jacpc_coupons_exists_code';
    private $couponsNumberKeyPrefix = 'jacpc_coupons_number_';

    /**
     * 查询一条记录通过条件
     * @param type $condition
     * @return type
     */
    public function getOne($condition){
        return $this->where($condition)->find(); 
    }
    
    /**
     * 保存卡券
     * @param type $data
     */
    public function saveCoupons($data){
         
        !empty($data['store_name']) && $saveData['store_name'] = $data['store_name'];
        !empty($data['store_logo']) && $saveData['store_logo'] = $data['store_logo'];
        !empty($data['color']) && $saveData['color'] = $data['color'];
        !empty($data['coupon_name']) && $saveData['coupon_name'] = $data['coupon_name'];
        !empty($data['coupon_name_sub']) && $saveData['coupon_name_sub'] = $data['coupon_name_sub'];
        !empty($data['date_type']) && $saveData['date_type'] = $data['date_type'];
        !empty($data['start_date']) && $saveData['start_date'] = $data['start_date'];
        !empty($data['end_date']) && $saveData['end_date'] = $data['end_date'];
        !empty($data['start_day']) && $saveData['start_day'] = $data['start_day'];
        !empty($data['end_day']) && $saveData['end_day'] = $data['end_day'];
        !empty($data['cover_logo']) && $saveData['cover_logo'] = $data['cover_logo'];
        !empty($data['cover_introduce']) && $saveData['cover_introduce'] = $data['cover_introduce'];
        !empty($data['cover_describe']) && $saveData['cover_describe'] = $data['cover_describe'];
        !empty($data['use_instruction']) && $saveData['use_instruction'] = $data['use_instruction'];
        !empty($data['get_limit']) && $saveData['get_limit'] = $data['get_limit'];
        !empty($data['number']) && $saveData['number'] = $data['number'];
        !empty($data['entrance']) && $saveData['entrance'] = $data['entrance'];
        !empty($data['href']) && $saveData['href'] = $data['href'];
        !empty($data['company_id']) && $saveData['company_id'] = $data['company_id'];
        !empty($data['brands_type']) && $saveData['brands_type'] = $data['brands_type'];
        !empty($data['store_type']) && $saveData['store_type'] = $data['store_type'];
        !empty($data['add_date']) && $saveData['add_date'] = $data['add_date'];
        !empty($data['api_user_id']) && $saveData['api_user_id'] = $data['api_user_id'];
        
        //判断是添加还是修改
        if(empty($data['id'])){
            //添加
            $result = $this->setTable("coupons")->insertGetId($saveData);
        }else{
            //修改
            $result = $this->setTable("coupons")->where(['id'=>$data['id'],'api_user_id'=>intval($data['api_user_id'])])->update($saveData);
        }
        
        // 添加和修改缓存
        if (isset($data['id']) && $result > 0 && isset($data['number_action_type'])) {
            $key = $this->getKey($data['id']);
            // 修改
            if (isset($data['number_action_type']) && isset($data['change_number']) &&
                    in_array($data['number_action_type'], ['incr', 'decr']) && $data['change_number'] > 0) {
                for ($i = 0; $i < 10; $i++) {
                    \think\Cache::watch($key);
                    $value = \think\Cache::get($key);
                    if ($value < 0) {
                        $value = 0;
                    }
                    if ($data['number_action_type'] == 'incr') {
                        $value += $data['change_number'];
                    } else {
                        $value -= $data['change_number'];
                        if ($value < 0) {
                            $value = 0; // 这块要优化啊，要优化
                        }
                    }
                    \think\Cache::multi();
                    \think\Cache::set($key, $value, $this->expire);
                    $res = \think\Cache::exec();

                    // 判断是否成功，如果成功就跳出循环
                    if ($res[0] == true) {
                        $result = $this->where(['id' => $data['id']])->update(["number" => $value]);
                        break;
                    }
                    sleep(0.2);
                }
            }
        } elseif(isset($data['number'])) {
            $id = isset($data['id']) ? $data['id'] : $result;
            $key = $this->getKey($id);

            // 添加库存缓存，10次不成功，数据就不一致了.
            $value = (int) $data['number'];
            for ($i = 0; $i < 10; $i++) {
                sleep(0.1);
                if (\think\Cache::set($key, $value, $this->expire) == $value) {
                    break;
                }
            }
        }
        
        return $result;
        
    }
    
    /**
     * 获取库存缓存key
     *
     * @return void
     */
    private function getKey($id) {
        return $this->couponsNumberKeyPrefix . $id;
    }
    
    
    /**
     * 领取优惠券
     * @param type $params
     * @param type $useData
     * @return boolean
     */
    public function receive($params, $useData) {
        $activity = $useData["activity"];
        $channel = $useData["channel"];
        $coupons = $useData["coupons"];
        $activityChannel = $useData["activityChannel"];
        
        \think\Cache::select(0);

        if (\think\Cache::get($this->getKey($coupons['id'])) <= 0) {
            // 没库存了
            $couponInfo = $this->where(['id' => $coupons['id']])->find();
            if ($couponInfo) {
                \think\Cache::set($this->getKey($coupons['id']), $couponInfo['number'], $this->expire);
            }else{
                return false;
            }
        }

        $number = \think\Cache::dec($this->getKey($coupons["id"]));
        if ($number >= 0) {
            // 可以生成优惠券了
            $data = [
                "coupon_id" => $coupons['id'],
                "sn" => \think\Cache::lPop($this->couponsExistsCodeKey),
                "status" => 0,
                "date" => $params['date'],
                "mobile" => $params['mobile'],
                "get_date" => $params['get_date'],
                "unique_id"=> isset($params['unique_id'])?$params['unique_id']:0
            ];
            //券码加上集团id(4位)20160611-小虎的需求
            $sn_company_id = str_pad($coupons["company_id"], 4, "0", STR_PAD_LEFT);
            $data["sn"] = $sn_company_id . $data["sn"];

            //  计算开始时间和结束时间
            if ($coupons['date_type'] == 1) {
                $data['start_date'] = strtotime(date('Y-m-d', $coupons['start_date']));
                $data['end_date'] = strtotime(date('Y-m-d', $coupons['end_date'])) + 86399;
            } else {
                $now = strtotime(date("Y-m-d", time()));
                $data['start_date'] = $now + 86400 * $coupons['start_day'];
                $data['end_date'] = $data['start_date'] + 86400 * ($coupons['end_day'] + 1) - 1;
            }
            $data['activity_id'] = $params['activity_id'];
            $data['channel_id'] = $params['channel_id'];
            if (!empty($params['vip_id']))
                $data['vip_id'] = $params['vip_id'];
            if (!empty($params['is_share']))
                $data['is_share'] = $params['is_share'];
            if (!empty($params['open_id']))
                $data['open_id'] = $params['open_id'];
            if (!empty($params['claim_open_id']))
                $data['claim_open_id'] = $params['claim_open_id'];
            if (!empty($params['claim_date']))
                $data['claim_date'] = $params['claim_date'];
            if (!empty($params['claim_mpid']))
                $data['claim_mpid'] = $params['claim_mpid'];

            // 生成优惠券
            //$couponsCoupTable = "coupons_coup_{$activity['company_id']}";
            //根据和小平商量leo改成券的company_id
            $couponsCoupTable = "coupons_coup_{$coupons['company_id']}";
            $result = $this->setTable($couponsCoupTable)->insertGetId($data);

            //  修改库存
            $this->setTable('coupons')->where(["id" => $coupons['id']])->update(['number' => $number]);
            return ["id" => $result, "code" => $data['sn'], 'coupon_id' => $data['coupon_id'], 'company_id' => $activity['company_id']];
        } else {
            // 没库存了
            return false;
        }
    }
    
    
    /**
     * 批量领取优惠券
     *
     */
    public function batchReceive($params, $useData) {
       $activity = $useData["activity"];
        $channel = $useData["channel"];
        $coupons = $useData["coupons"];
        $activityChannel = $useData["activityChannel"];

        \think\Cache::select(0);
        if (\think\Cache::get($this->getKey($coupons['id'])) <= 0) {
            // 没库存了
            $couponInfo = $this->where(['id' => $coupons['id']])->find();
            if ($couponInfo) {
                \think\Cache::set($this->getKey($coupons['id']), $couponInfo['number'], $this->expire);
            }else{
                return false;
            }
        }

        $number = \think\Cache::get($this->getKey($coupons["id"]));
         
        if (intval($number) >= intval($params['coupons_num'])  && intval($params['coupons_num']) > 0) {
            //讲卡券数量剪掉
            $remain_num = intval($number) - intval($params['coupons_num']);
            \think\Cache::set($this->getKey($coupons['id']),$remain_num);
            
            //次数
            $times = $params['coupons_num'] + 50;//给多出50次的重试机会，达到足够的券退出
            
            while($times--){
                // 可以生成优惠券了
                $data = [
                    "coupon_id" => $coupons['id'],
                    "sn" => \think\Cache::lPop($this->couponsExistsCodeKey),
                    "status" => 0,
                    "date" => $params['date'],
                    "mobile" => $params['mobile'],
                    "get_date" => $params['get_date'],
                    'unique_id'=>$params['unique_id'],
                ];
                //券码加上集团id(4位)20160611-小虎的需求
                $sn_company_id = str_pad($coupons["company_id"], 4, "0", STR_PAD_LEFT);
                $data["sn"] = $sn_company_id . $data["sn"];

                //  计算开始时间和结束时间
                if ($coupons['date_type'] == 1) {
                    $data['start_date'] = strtotime(date('Y-m-d', $coupons['start_date']));
                    $data['end_date'] = strtotime(date('Y-m-d', $coupons['end_date'])) + 86399;
                } else {
                    $now = strtotime(date("Y-m-d", time()));
                    $data['start_date'] = $now + 86400 * $coupons['start_day'];
                    $data['end_date'] = $data['start_date'] + 86400 * ($coupons['end_day'] + 1) - 1;
                }
                $data['activity_id'] = $params['activity_id'];
            $data['channel_id'] = $params['channel_id'];
                if (!empty($params['vip_id']))
                    $data ['vip_id'] = $params['vip_id'];
                if (!empty($params['is_share']))
                    $data ['is_share'] = $params['is_share'];
                if (!empty($params['open_id']))
                    $data ['open_id'] = $params['open_id'];
                if (!empty($params['claim_open_id']))
                    $data ['claim_open_id'] = $params['claim_open_id'];
                if (!empty($params['claim_date']))
                    $data ['claim_date'] = $params['claim_date'];
                if (!empty($params['claim_mpid']))
                    $data ['claim_mpid'] = $params['claim_mpid'];

                // 生成优惠券
                //$couponsCoupTable = "coupons_coup_{$activity['company_id']}";
                //根据和小平商量leo改成券的company_id
                $couponsCoupTable = "coupons_coup_{$coupons['company_id']}";
                $result = $this->setTable($couponsCoupTable)->insertGetId($data);
                
                $returnData[] = ["id" => $result, "code" => $data['sn'], 'coupon_id' => $data['coupon_id'], 'company_id' => $coupons['company_id']];
                
                if(count($returnData) >= intval($params['coupons_num'])){
                    break;
                }
            }
            
           //  修改库存
            if ($times >= 0) {
                //  修改库存
                 $this->setTable('coupons')->where(["id" => $coupons['id']])->update(['number' => $remain_num]);
                return $returnData;
            }else{
                return false;
            }
            

        } else {
            // 没库存了
            return false;
        }
    }
    
    
    /**
     * 根据卡券id获取叽叽券信息
     * @param type $couponsId 卡券id
     * @param type $companyId 公司id
     * @return type
     */
    public function getCouponsInfoById($couponsId, $companyId) {
        $condition = [
            'id' => $couponsId,
            'company_id'=>$companyId
        ];
        
        $info = $this->where($condition)->find();
        return $info;
    }
    
    
    /**
     * 获取优惠券列表
     * @param type $company_id
     * @param type $params
     * @return 
     */
    public function Lists($company_id, $params) {
        $list = $where = [];
        $where = [
            'company_id' => $company_id,
        ];
        
        if (!empty($params['keywords'])) {
            $where['coupon_name'] = ['like', "%{$params['keywords']}%"];
        }


        $page = isset($params['page']) ? (int) $params['page'] : 1;
        $count = $this->where($where)->count();
        
        if (!empty($count)) {
            $pageSize = isset($params['pageSize']) ? (int) $params['pageSize'] : 10;

            $list = $this->field([
                'coupons.id', 'coupons.store_name', 'coupons.coupon_name', 'coupons.coupon_name_sub',
                'coupons.date_type', 'coupons.start_date', 'coupons.end_date', 'coupons.start_day',
                'coupons.end_day', 'coupons.number', 'coupons.coupon_type',
                'coupons.add_date'
                    ])->order('coupons.id DESC')->page($page,$pageSize)->where($where)->select();
            
            foreach ($list as $key => $val) {

                $sql = 'SELECT SUM("use_number") as usen, SUM("get_number") as getn FROM coupon_count WHERE "coupon_id" = ' . $val['id'];
                $number = $this->query($sql);
                if ($number) {
                    $number = current($number);
                }
                $list[$key]['get_number'] = (int) $number['getn'];
                $list[$key]['use_number'] = (int) $number['usen'];
            }
        }

        $data = [
            'page' => $page,
            'count' => (int) $count,
            'list' => $list
        ];
        return $data;
    }
    
    
     /**
      * 编辑活动时，获取优惠券列表
      * @param type $company_id
      * @param type $keywords
      * @param type $page
      * @param type $pageSize
      * @return type
      */
    public function ListsForEditActivity($company_id, $keywords,$page,$pageSize) {
        $list = $where = [];
        $where = [
            'coupons.company_id' => $company_id
        ];
        if (!empty($keywords)) {
            $where['coupons.coupon_name'] =  ['like',"%{$keywords}%"];
        }
        
        $join = [
            ['sales_activity sales_activity','sales_activity.coupons_id = coupons.id','LEFT']
        ];

        $time = time();
        
        $count = $this->alias('coupons')->join($join)->where($where)
                ->where(" coupons.end_date >= {$time} or coupons.date_type=2 ")
                ->whereNull('sales_activity.activity_name')->count();

        $pageSize = $pageSize < 1?1:intval($pageSize);
        $page     = $page < 1 ? 1:$page;

        if (!empty($count)) {
            
            $field = [
                'coupons.id',
                'coupons.store_name',
                'coupons.coupon_name',
                'coupons.coupon_name_sub',
                'coupons.date_type',
                'coupons.start_date',
                'coupons.end_date',
                'coupons.start_day',
                'coupons.end_day',
                'coupons.number',
                'coupons.coupon_type',
                'sales_activity.activity_name',
                'coupons.add_date'
            ];
            
            $list = $this->alias('coupons')->field($field)->join($join)
                    ->where($where)->order('coupons.id DESC')
                    ->where(" coupons.end_date >= {$time} or coupons.date_type=2 ")
                    ->whereNull('sales_activity.activity_name')
                    ->page($page,$pageSize)->select();
        }

        $data = [
            'page' => $page,
            'count' => intval($count),
            'list' => $list
        ];
        
        return $data;
    }
}